package cn.smart.epic.core.shiro.factory;

import cn.smart.epic.common.constant.factory.ConstantFactory;
import cn.smart.epic.common.constant.state.ManagerStatus;
import cn.smart.epic.common.persistence.dao.MenuMapper;
import cn.smart.epic.common.persistence.dao.UserMapper;
import cn.smart.epic.common.persistence.model.User;
import cn.smart.epic.core.shiro.ShiroUser;
import cn.smart.epic.core.util.Convert;
import cn.smart.epic.core.util.SpringContextHolder;
import org.apache.shiro.authc.CredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;

import static java.util.stream.Collectors.toList;

/**
 * @Auther Z.B
 * @date 2017/10/11 14:32
 * @Email 2545375@qq.com
 * @Description 请输入你的描述
 * @since 1.0
 */

@Service
@DependsOn("springContextHolder")
@Transactional(readOnly = true)
public class ShiroFactroy implements IShiro {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private MenuMapper menuMapper;

    public static IShiro me(){
        return SpringContextHolder.getBean(IShiro.class);
    }

    @Override
    public User user(String account) {
        User user = userMapper.getByAccount(account);

        //帐号被冻结
        if (user == null) {
            throw new CredentialsException();
        }

        //帐号不存在
        if (user.getStatus() != ManagerStatus.OK.getCode()) {
            throw new LockedAccountException();
        }

        return user;
    }

    @Override
    public ShiroUser shiroUser(User user) {
        ShiroUser shiroUser=new ShiroUser();

        shiroUser.setId(user.getId());
        shiroUser.setAccount(user.getAccount());
        shiroUser.setDeptId(user.getDeptid());
        shiroUser.setDeptName(ConstantFactory.me().getDeptName(user.getDeptid()));
        shiroUser.setName(user.getName());

        Integer[] roleArray= Convert.toIntArray(user.getRoleid());
        shiroUser.setRoleList(Arrays.stream(roleArray).collect(toList()));
        shiroUser.setRoleNames(Arrays.stream(roleArray).
                map(ConstantFactory.me()::getSingleRoleName).collect(toList()));

        return shiroUser;
    }

    @Override
    public List<String> findPermissionByRoleId(Integer roleId) {
        List<String> resUrl = menuMapper.getResUrlsByRoleId(roleId);
        return resUrl;
    }

    @Override
    public String findRoleNameByRoleId(Integer roleid) {
        return ConstantFactory.me().getSingleRoleTip(roleid);
    }

    @Override
    public SimpleAuthenticationInfo info(ShiroUser shiroUser, User user, String realmName) {
        String credentials = user.getPassword();
        String source = user.getSalt();
        ByteSource credentialsSlat = new Md5Hash(source);
        return new SimpleAuthenticationInfo(shiroUser,credentials,credentialsSlat,realmName);
    }
}
